package adoption;

import exception.InvalidStatusException;


/**
 * Represents valid statuses of book adoptions.
 * @author SJP
 *
 */
public class Status {
	
	/**
	 * Valid status strings
	 */
	private static String reqS = "Required",
				   		  optS = "Optional",
				   		  altS = "Alternate",
				   		  pcS = "Package Component",
				   		  errorS = "ERROR";
	
	private static Status req = new Status(reqS),
						  opt = new Status(optS),
						  alt = new Status(altS),
						  pc = new Status(pcS),
						  error = new Status(errorS);
	
	/**
	 * This status string
	 */
	private String status;
	
	/**
	 * Create new status object with the given string.
	 * ASSUMES THE STRING IS VALID.
	 * @param stat
	 */
	public Status(String stat) {
		status = stat;
	}
	
	/**
	 * @return true if status is required, else false.
	 */
	public boolean isReq() {return is(reqS);}
	
	/**
	 * @return true if status is optional, else false.
	 */
	public boolean isOpt() {return is(optS);}
	
	/**
	 * @return true if status is alternate, else false.
	 */
	public boolean isAlt() {return is(altS);}
	
	/**
	 * @return true if status is package component, else false.
	 */
	public boolean isPC() {return is(pcS);}
	
	/**
	 * @return true if status is error, else false.
	 */
	public boolean isError() {return is(errorS);}
	
	/**
	 * @return true if status matches the given string, else false.
	 */
	private boolean is(String s) {return status.equals(s);}

	/**
	 * @return the status as a string.
	 */
	public String toString() {return status;}
	
	/**
	 * @return true if s is a valid status string.
	 */
	public static boolean isValid(String s) {
		if (s.equals(error))
			return false;
		boolean out = false;
		out |= s.equals(reqS);
		out |= s.equals(optS);
		out |= s.equals(altS);
		out |= s.equals(pcS);
		
		return out;
	}
	
	/**
	 * Returns the proper Status object for a given status string.
	 * @param s status string
	 * @return a static Status object for the given string
	 * @throws InvalidStatusException if an invalid status string is given
	 */
	public static Status getStatus(String s) throws InvalidStatusException{
		
		// check invalid status
		if (!isValid(s))
			throw new InvalidStatusException("Status \""+s+"\" is not valid.");
		
		// check each valid type of status
		if (s.equals(req.toString()))
			return req;
		else if (s.equals(opt.toString()))
			return opt;
		else if (s.equals(alt.toString()))
			return alt;
		else if (s.equals(pc.toString()))
			return pc;
		
		//shouldn't reach here, error case.
		throw new InvalidStatusException("Status \""+s+"\" is not valid. Weirdo.");
			
	}
}
